package com.android.aiod.manager;

import android.widget.TextView;

import com.android.aiod.bean.SerailDataInfo_Base;
import com.android.aiod.utils.CRCUtils;
import com.android.baselibrary.interface_.CommCallBack;
import com.android.baselibrary.tool.Log;
import com.blankj.utilcode.util.ConvertUtils;
import com.licheedev.hwutils.ByteUtil;

import java.nio.ByteBuffer;
/**
 * 数据解析类
 */
public class DataParsingManager {

    public static SerailDataInfo_Base parsingData(byte[] byte_source, TextView tv_log) {
//        tv_log.setText(tv_log.getText() + ">>>>>>接收到数据，长度：" + byte_source.length + "\n" + ByteUtil.bytes2HexStr(byte_source) + "\n");
        Log.i(">>>>>>接收到数据：" + ByteUtil.bytes2HexStr(byte_source) + "\n");
        //数据源
        SerailDataInfo_Base dateInfo = new SerailDataInfo_Base();
        //头部
        dateInfo.bytes_head = new byte[4];
        System.arraycopy(byte_source, 0, dateInfo.bytes_head, 0, 4);
        //长度
        dateInfo.bytes_length = new byte[4];
        System.arraycopy(byte_source, 4, dateInfo.bytes_length, 0, 4);
        //data部分
        dateInfo.bytes_data = new byte[dateInfo.getDataLength()];
        System.arraycopy(byte_source, 8, dateInfo.bytes_data, 0, dateInfo.bytes_data.length);
        //显示文字 CMD 1+ LIG 1+ COL 1+ CODE + RES 8
        dateInfo.byte_CMD = new byte[]{dateInfo.bytes_data[0]};
        //CRC
        dateInfo.bytes_CRC = new byte[2];
        System.arraycopy(byte_source, 8 + dateInfo.bytes_data.length, dateInfo.bytes_CRC, 0, 2);

        //判断指令
        String CMD_Str = dateInfo.getCMD_Str();
        if ("A3".equals(CMD_Str)) {
            //清除文字
//            Log.i("清除文字");

        } else {
            if ("A4".equals(CMD_Str)) {
//                Log.i("显示文字");
                dateInfo.byte_transparency = new byte[]{dateInfo.bytes_data[1]};
                dateInfo.byte_color = new byte[]{dateInfo.bytes_data[2]};
                dateInfo.bytes_code = new byte[dateInfo.bytes_data.length - 11];
                System.arraycopy(dateInfo.bytes_data, 3, dateInfo.bytes_code, 0, dateInfo.bytes_code.length);
            } else if ("A6".equals(CMD_Str)) {
                //播放语音
                dateInfo.byte_voice = new byte[]{dateInfo.bytes_data[1]};
                dateInfo.bytes_code = new byte[dateInfo.bytes_data.length - 10];
                System.arraycopy(dateInfo.bytes_data, 2, dateInfo.bytes_code, 0, dateInfo.bytes_code.length);
            } else {
//                Log.i("指令无效");
//                tv_log.setText(tv_log.getText() + "指令无效" + "\n");
                dateInfo.error = 0x02;
            }
        }
//        tv_log.setText(tv_log.getText() + "DATA数据：" + ByteUtil.bytes2HexStr(dateInfo.bytes_data) + "\n");
//        tv_log.setText(tv_log.getText() + "length长度：" + dateInfo.getDataLength() + "\n");
//        tv_log.setText(tv_log.getText() + "DATA的实际长度：" + (byte_source.length - 4 - 4 - 2) + "\n");

//        Log.i("返回 length:" + dateInfo.getDataLength() + "  实际length:" + (byte_source.length - 4 - 4 - 2));
        if (dateInfo.getDataLength() != (byte_source.length - 4 - 4 - 2)) {
//            CommToast.showToast(MyApplication.context, "data长度不对");
//            tv_log.setText(tv_log.getText() + "data长度不对" + "\n");
            dateInfo.error = 0x03;
        }
        if (dateInfo.bytes_head[3] < 0x11 || dateInfo.bytes_head[3] > 0x19) {
            Log.i("电脑端序列号不对");
//            tv_log.setText(tv_log.getText() + "电脑端序列号不对" + "\n");
            dateInfo.error = 0x04;
        }

        byte[] bytes_VER = {dateInfo.bytes_head[2]};
        byte[] bytes_SEQ = {dateInfo.bytes_head[3]};
        //从 VER 至 DATA 所有字节的 CRC-16/X25 校验值。
        ByteBuffer byteBuffer_CRC = ByteBuffer.allocate(bytes_VER.length + bytes_SEQ.length + dateInfo.bytes_length.length + dateInfo.bytes_data.length);
        byteBuffer_CRC.put(bytes_VER);
        byteBuffer_CRC.put(bytes_SEQ);
        byteBuffer_CRC.put(dateInfo.bytes_length);
        byteBuffer_CRC.put(dateInfo.bytes_data);
        byte[] bytes_CRC_Temp = byteBuffer_CRC.array();
        String str_CRC = ConvertUtils.bytes2HexString(dateInfo.bytes_CRC);
        String str_CRC1 = CRCUtils.CRC_16_X25(bytes_CRC_Temp);   //本地计算的CRC


//        Log.i("bytes_CRC_Temp:"+ ConvertUtils.bytes2HexString(bytes_CRC_Temp));
//
//        Log.i("CRC 校验str_CRC:" + str_CRC + "  str_CRC1:" + str_CRC1  );
        if (!str_CRC1.equals(str_CRC)) {
//            dateInfo.error = 0x01;
//            tv_log.setText(tv_log.getText() + "CRC校验不对: 串口返回CRC：" + str_CRC + " 本地计算CRC：" + str_CRC1 + "\n");
        }
        return dateInfo;
    }

    //组成返回的数据包
    public static byte[] createReturnData(SerailDataInfo_Base dataInfo, TextView tv_log) {
        //START + VER + SEQ (4 ) +  LEN(4) + DATA + CRC(2)。
        //头部
        byte[] bytes_START = {(byte) 0xFF, (byte) 0xFF};    //固定值
        byte[] bytes_VER = {(byte) 0x01};
        byte[] bytes_SEQ = {(byte) 0x81};

        //长度
        byte[] bytes_length;
        //正应答：Data = CMD + SEC + SEQ + RES
        //负应答：Data = CMD + SEC + SEQ + Err + RES
        byte[] bytes_CMD;
        if (dataInfo.error == 0) {
            bytes_CMD = new byte[]{(byte) 0xF1};
        } else {
            bytes_CMD = new byte[]{(byte) 0xF2};
        }

        byte[] bytes_SEC = ByteUtil.long2bytes(System.currentTimeMillis(), 4);
        byte[] bytes_SEQ1 = {dataInfo.bytes_head[3]};
        byte[] bytes_ERR;
        byte[] bytes_RES = new byte[4];
        if (dataInfo.error == 0) {
            bytes_ERR = new byte[0];
        } else {
            bytes_ERR = new byte[]{(byte) 0x00, dataInfo.error};
        }

        ByteBuffer byteBuffer = ByteBuffer.allocate(bytes_CMD.length + bytes_SEC.length + bytes_SEQ1.length + bytes_ERR.length + bytes_RES.length);
        byteBuffer.put(bytes_CMD);
        byteBuffer.put(bytes_SEC);
        byteBuffer.put(bytes_SEQ1);
        byteBuffer.put(bytes_ERR);
        byteBuffer.put(bytes_RES);
        byte[] bytes_data = byteBuffer.array();
        bytes_length = intToByte(bytes_data.length);

        //从 VER 至 DATA 所有字节的 CRC-16/X25 校验值。
        ByteBuffer byteBuffer_CRC = ByteBuffer.allocate(bytes_VER.length + bytes_SEQ.length + bytes_length.length + bytes_data.length);
        byteBuffer_CRC.put(bytes_VER);
        byteBuffer_CRC.put(bytes_SEQ);
        byteBuffer_CRC.put(bytes_length);
        byteBuffer_CRC.put(bytes_data);
        byte[] bytes_CRC_Temp = byteBuffer_CRC.array();

        String str_CRC1 = CRCUtils.CRC_16_X25(bytes_CRC_Temp);
        Log.i("str_CRC1：" + str_CRC1);
        byte[] bytes_CRC = ConvertUtils.hexString2Bytes(str_CRC1); //获取检验码

        //组成最终包
        ByteBuffer byteBuffer_final = ByteBuffer.allocate(bytes_START.length + bytes_VER.length + bytes_SEQ.length + bytes_length.length + bytes_data.length + bytes_CRC.length);
        byteBuffer_final.put(bytes_START);
        byteBuffer_final.put(bytes_VER);
        byteBuffer_final.put(bytes_SEQ);
        byteBuffer_final.put(bytes_length);
        byteBuffer_final.put(bytes_data);
        byteBuffer_final.put(bytes_CRC);
        byte[] bytes_final = byteBuffer_final.array();

        if (dataInfo.error == 0) {
            Log.i("返回正应答：" + ConvertUtils.bytes2HexString(bytes_final));
            tv_log.setText(tv_log.getText() + "返回正应答：" + ConvertUtils.bytes2HexString(bytes_final) + "\n");
        } else {
            tv_log.setText(tv_log.getText() + "返回负应答：" + ConvertUtils.bytes2HexString(bytes_final) + "\n");
            Log.i("返回负应答：" + ConvertUtils.bytes2HexString(bytes_final));
        }
        return bytes_final;
    }

    private static byte[] intToByte(int i) {
        byte[] result = new byte[4];
        // 由高位到低位
        result[0] = (byte) ((i >> 24) & 0xFF);
        result[1] = (byte) ((i >> 16) & 0xFF);
        result[2] = (byte) ((i >> 8) & 0xFF);
        result[3] = (byte) (i & 0xFF);
        return result;
    }


    //收到数据进行组包
    boolean isBegin = false;
    int length_all = 0;
    int length_added = 0;
    ByteBuffer byteBuffer_final;
    CommCallBack callBack;

    public DataParsingManager(CommCallBack callBack) {
        this.callBack = callBack;
    }

    public void ReceiveData(byte[] byte_source) {
        //收到数据开始
        if (byte_source[0] == (byte) 0xFF && byte_source[1] == (byte) 0xFF) {
            if (!isBegin) {
                isBegin = true;
                //长度
                byte[] bytes_length = new byte[4];
                System.arraycopy(byte_source, 4, bytes_length, 0, 4);
                //data数据长度
                int length_data = (int) ByteUtil.bytes2long(bytes_length);
                //数据总长度
                length_all = length_data + 10;
                //生成总数据
                byteBuffer_final = ByteBuffer.allocate(length_all);
                byteBuffer_final.put(byte_source);
                length_added += byte_source.length;
            }
        } else {
            if (isBegin) {
                //判断长度
                if (length_added + byte_source.length <= length_all) {
                    byteBuffer_final.put(byte_source);
                    length_added += byte_source.length;
                }
            }
        }

        //最后判断数据收完整了没
        if (length_added == length_all) {
            //组包完成，返回
            byte[] bytes_final = byteBuffer_final.array();
            callBack.onResult(bytes_final);

            isBegin = false;
            length_all = 0;
            length_added = 0;
            byteBuffer_final = null;
        }
    }

}
